package com.sec.android.app.myfiles.fragment.settings;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.TextView;

import com.samsung.android.sdk.slinkcloud.CloudGatewayConstants;
import com.samsung.android.sdk.slinkcloud.CloudGatewayStorageUtils;
import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.feature.CloudMgr;
import com.sec.android.app.myfiles.feature.cloud.AbsCloudImp;
import com.sec.android.app.myfiles.info.AppConstants;
import com.sec.android.app.myfiles.info.AppFeatures;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.log.SamsungAnalyticsLog;
import com.sec.android.app.myfiles.module.abstraction.FileRecord.CloudType;
import com.sec.android.app.myfiles.module.cloud.CloudFileRecord;

import java.util.ArrayList;

public class SelectAccountFragment extends AbsSettingsFragment implements CloudMgr.CloudStateListener {
    private static final String ACCOUNT_LIST_CHANGED = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
    private static final int REQUEST_CODE_SIGN_CLOUD = 100;
    private Context mContext;
    private CloudMgr mCloudMgr;
    private ListView mAccountListView;
    private AccountAdapter mAccountAdapter;
    private BroadcastReceiver mAccountListChangeReciver;
    private CloudType mCloudType = null;
    private SamsungAnalyticsLog.ScreenPath mScreenPath;
    private boolean mIsChoosingAccount, mIsSigningCloud;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        mContext = getContext();
        View rootView = inflater.inflate(R.layout.select_account_layout, container, false);
        mCloudMgr = CloudMgr.getInstance(mContext);
        mCloudMgr.addListener(this);

        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        setAccountFragment(view);
        registerReceiver(view);
    }

    private void setAccountFragment(View rootView) {
        if (getArguments() != null && rootView != null) {
            mCloudType = CloudFileRecord.getCloudType(getArguments().getString(SettingsFragment.SIGN_IN_CLOUD_TYPE));
            mScreenPath = (mCloudType == CloudType.SamsungDrive) ? SamsungAnalyticsLog.ScreenPath.SETTINGS_SAMSUNG_CLOUD_ACCOUNT : SamsungAnalyticsLog.ScreenPath.SETTINGS_GOOGLE_CLOUD_ACCOUNT;
            mActivity.setScreenPath(mScreenPath);

            setActionBatTitle(mCloudType);
            showAccountList(rootView);
            if (mCloudType.compareTo(CloudType.SamsungDrive) != 0) {
                setAddAccountView(rootView);
            }
        }
    }

    private void setActionBatTitle(CloudType type) {
        if (mActivity != null && mCloudMgr != null) {
            int accountId;
            AbsCloudImp cloudImp = mCloudMgr.getCloudImp(type);
            if (cloudImp != null) {
                switch (cloudImp.getCloudName()) {
                    case AppConstants.CloudType.GOOGLE_DRIVE:
                        accountId = R.string.select_google_account;
                        break;
                    case AppConstants.CloudType.SAMSUNG_DRIVE:
                        accountId = (AppFeatures.IS_JPN) ? R.string.select_galaxy_account : R.string.select_samsung_account;
                        break;
                    default:
                        accountId = R.string.myfiles_settings;
                        break;
                }

                mActivity.setActionBar(accountId);
            }
        }
    }

    private void showAccountList(View rootView) {
        try {
            if (mActivity != null && mCloudType != null) {
                AccountManager accountManager = AccountManager.get(mActivity);
                Account[] accounts = accountManager.getAccountsByType(mCloudMgr.getAccountType(mCloudType));
                final long numberOfAccounts = accounts.length;

                mAccountListView = (ListView) rootView.findViewById(R.id.account_list);
                mAccountAdapter = new AccountAdapter(mContext, R.layout.account_list_item);
                if (accounts.length > 0) {
                    for (Account account : accounts) {
                        mAccountAdapter.addAccount(account.name);
                    }
                }

                mAccountAdapter.setCurrentAccount(mCloudMgr.getUserId(mCloudType));
                mAccountListView.setAdapter(mAccountAdapter);
                mAccountListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
                mAccountListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        changeAccount(position, numberOfAccounts);
                    }
                });
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

    private void setAddAccountView(View rootView) {
        final View addAccount = rootView.findViewById(R.id.add_account_view);
        final TextView tv = (TextView) rootView.findViewById(R.id.add_account_text_id);
        addAccount.setVisibility(View.VISIBLE);
        addAccount.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SamsungAnalyticsLog.sendLog(mScreenPath, SamsungAnalyticsLog.Event.ADD_ACCOUNT, null);
                signInAccount(CloudGatewayConstants.ADD_ACCOUNT);
            }
        });
    }

    public void changeAccount(int position, Long numberOfAccounts) {
        if (position != mAccountAdapter.getPosition(mAccountAdapter.getCurrentAccount())) {
            String account = mAccountAdapter.getItem(position);
            mIsChoosingAccount = true;
            if (account != null) {
                SamsungAnalyticsLog.sendLog(mScreenPath, SamsungAnalyticsLog.Event.SELECT_ITEM, numberOfAccounts, null);
                signInAccount(account);
            } else {
                SamsungAnalyticsLog.sendLog(mScreenPath, SamsungAnalyticsLog.Event.SIGN_OUT, null);
                signOutAccount();
            }

            mAccountAdapter.setCurrentAccount(account);
            mAccountAdapter.notifyDataSetChanged();
        }
    }

    public void signInAccount(String account) {
        if (mCloudType != null) {
            mIsSigningCloud = true;
            Intent intent = CloudGatewayStorageUtils.getInstance(mContext).createStorageSignInIntent(CloudFileRecord.getCloudName(mCloudType));
            intent.putExtra(CloudGatewayConstants.SIGN_IN_ACCOUNT, account);
            startActivityForResult(intent, REQUEST_CODE_SIGN_CLOUD);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_SIGN_CLOUD) {
            mIsSigningCloud = false;
            if (resultCode == Activity.RESULT_CANCELED) {
                setAccountFragment(getView());
            }
        }
    }

    public void signOutAccount() {
        if (mCloudMgr.isSignedIn(mCloudType)) {
            CloudGatewayStorageUtils.getInstance(mContext).signOutOfStorageService(mCloudMgr.getDeviceId(mCloudType));
        }
    }

    private void registerReceiver(final View rootView) {
        IntentFilter filter = new IntentFilter(ACCOUNT_LIST_CHANGED);

        mAccountListChangeReciver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (ACCOUNT_LIST_CHANGED.equals(intent.getAction())) {
                    showAccountList(rootView);
                }
            }
        };

        mContext.registerReceiver(mAccountListChangeReciver, filter);
    }

    private void unregisterReceiver() {
        if (mAccountListChangeReciver != null)
            mContext.unregisterReceiver(mAccountListChangeReciver);
    }

    @Override
    public void onPause() {
        super.onPause();
        if (!mIsSigningCloud) {
            mIsChoosingAccount = false;
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mCloudMgr.removeListener(this);
        unregisterReceiver();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setAccountFragment(getView());
    }

    @Override
    public void onCloudInit() {
    }

    @Override
    public void onAccountChanged(CloudType cloudType) {
        Log.d(this, "onAccountChanged() - cloudType : " + cloudType);
        if (mCloudType != null && mCloudType == cloudType && !mIsChoosingAccount) {
            setAccountFragment(getView());
        }
    }

    private class AccountAdapter extends ArrayAdapter<String> {
        private LayoutInflater mInflater;
        private int mLayout;
        private String mCurrentAccount;
        private ArrayList<String> mAccountList;

        public AccountAdapter(Context context, int layout) {
            super(context, layout);
            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mLayout = layout;
            mAccountList = new ArrayList<>();
            mAccountList.add(null);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = mInflater.inflate(mLayout, parent, false);
            }
            final CheckedTextView account = (CheckedTextView) convertView.findViewById(R.id.account_title);

            boolean isCurrentAccount = (mAccountList.indexOf(mCurrentAccount) == position);
            account.setText(getAccountFromList(position));
            account.setChecked(isCurrentAccount);
            return convertView;
        }

        public String getAccountFromList(int position) {
            return (position != 0) ? mAccountList.get(position) : getString(R.string.sign_out);
        }

        public void setCurrentAccount(String account) {
            mCurrentAccount = account;
        }

        public String getCurrentAccount() {
            return mCurrentAccount;
        }

        public void addAccount(String account) {
            mAccountList.add(account);
        }

        @Override
        public int getCount() {
            return mAccountList.size();
        }

        @Override
        public String getItem(int position) {
            return mAccountList.get(position);
        }

        @Override
        public int getPosition(String item) {
            return (item != null) ? mAccountList.indexOf(item) : 0;
        }
    }
}
